package com.xwb.laboratory.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;

public class ThreadDemo {

	private Integer i;
	
//	public static void main(String[] args) throws Exception {
//		ThreadDemo thread = new ThreadDemo();
//		thread.testState();
//	}
	
	public void test1() throws Exception {
		Thread t1 = new Thread(() -> {
			if(i == null) {
				System.out.println("没拿到冰淇淋，等待中。。。");
				System.out.println(this);
				synchronized (this) {					
					Thread.currentThread().suspend();
				}
			}
			System.out.println("拿到冰淇淋。。。");
		});
		
		t1.start();
		
		Thread.sleep(3000L);
		System.out.println("通知小朋友");
		System.out.println(this);
		synchronized (this) {			
			t1.resume();
		}
	}
	
	public void testState() throws Exception {
		Thread t1 = new Thread(() -> {
			try {
				Thread.sleep(3000L);
				LockSupport.park();
				Thread.sleep(2000L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		
		System.out.println("1." + t1.getState());
		
		Thread.sleep(3000L);
		
		t1.start();
		
		Thread.sleep(1000L);
		
		System.out.println("2." + t1.getState());
		
		Thread.sleep(4000L);
		
		System.out.println("3." + t1.getState());
		
		Thread.sleep(3000L);
		
		LockSupport.unpark(t1);
		
		Thread.sleep(1000L);
		
		System.out.println("4." + t1.getState());
		
		Thread.sleep(3000L);
		
		System.out.println("5." + t1.getState());
	}
	
	public void testInterrupt() throws InterruptedException {
		i = 1;
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (i) {
					try {
						System.out.println("等待。。。");
						i.wait();
						System.out.println("等待结束");
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
			}
		});
		
		t.start();
		
		Thread.sleep(1000L);
		
		synchronized (i) {			
			System.out.println("通知。。。");
			i.notify();
		}
	}
	
	void testPark() throws InterruptedException {
		Thread t1 = new Thread(() -> {
			while(true) {
				LockSupport.park();
				
				System.out.println("子线程输出。。。");
			}
		});
		
		t1.start();
		Thread.sleep(1000);
		t1.interrupt();
		System.out.println("main thread end...");
	}
	
	void test2() throws InterruptedException, ExecutionException {
		Callable<String> callable = new Callable<String>() {
			
			@Override
			public String call() throws Exception {
				Thread.sleep(1000L);
				return "callable线程";
			}
		};
		
		FutureTask<String> futureTask = new FutureTask<>(callable);
		new Thread(futureTask).start();
		
		System.out.println("主线程111");
		System.out.println(futureTask.get());
		System.out.println("主线程222");
	}
	
	void test3() throws InterruptedException, ExecutionException {
		List<Callable<String>> list = new ArrayList<>();
		Callable<String> callable1 = new Callable<String>() {
			@Override
			public String call() throws Exception {
				Thread.sleep(1000L);
				return "callable11111线程";
			}
		};
		list.add(callable1);
		Callable<String> callable2 = new Callable<String>() {
			@Override
			public String call() throws Exception {
				Thread.sleep(1000L);
				return "callable22222线程";
			}
		};
		list.add(callable2);
		Callable<String> callable3 = new Callable<String>() {
			@Override
			public String call() throws Exception {
				Thread.sleep(1000L);
				return "callable33333线程";
			}
		};
		list.add(callable3);
		Callable<String> callable4 = new Callable<String>() {
			@Override
			public String call() throws Exception {
				Thread.sleep(1000L);
				return "callable44444线程";
			}
		};
		list.add(callable4);
		ExecutorService executor = Executors.newFixedThreadPool(4);
		List<Future<String>> taskList = executor.invokeAll(list);
		for(Future<String> task : taskList) {
			System.out.println(task.get());
		}
	}
	
	void test4() throws InterruptedException, ExecutionException {
		Callable<String> callable = new Callable<String>() {
			
			@Override
			public String call() throws Exception {
				Thread.sleep(2000L);
				System.out.println("callable线程。。。");
				return "callable线程执行完";
			}
		};
		
		MyFutureTask<String> myFutureTask = new MyFutureTask<>(callable);
		new Thread(myFutureTask).start();
		
		//Thread.sleep(3000);
		System.out.println("主线程111");
		System.out.println(myFutureTask.get());
		System.out.println("主线程222");
	}
	
	void testState2() throws InterruptedException {
		Thread t = new Thread(() -> {
			//LockSupport.park();
			try {
				Thread.sleep(3000L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		t.start();
		Thread.sleep(1000);
		System.out.println(t.getState().toString());
		//LockSupport.unpark(t);
		t.interrupt();
		Thread.sleep(1000);
		System.out.println(t.getState().toString());
	}
	
	void testInterrupt2() throws InterruptedException {
		Thread t = new Thread(() -> {
			while(!Thread.currentThread().isInterrupted()) {
				try {
					System.out.println("子线程运行中......");
					//Thread.sleep(1000L);
				} catch (Exception e) {
					System.out.println("子线程报异常了......");
					e.printStackTrace();
					//Thread.currentThread().interrupt();
				}
			}
		});
		t.start();
		
		Thread.sleep(3000L);
		System.out.println("在此打断。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
		t.interrupt();
		
	}
	
	public Map<String, Object> getInfo(){
		// 创建线程
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
				5,      //核心线程数
				10,     //最大线程数
				5,      //keepAliveTime，超过核心线程数的线程，超过 keepAliveTime，就会被销毁
				TimeUnit.SECONDS,     //keepAliveTime的单位
				new LinkedBlockingQueue<>(10)    //工作队列，线程池执行的任务将会放到这个队列中
		);
		
		Callable<String> c1 = () -> {
			// 调用用户服务获取基本信息
			String r = getUserInfo();
			return r;
		};
		// 执行任务
		Future<String> f1 = threadPoolExecutor.submit(c1);
		
		Callable<String> c2 = () -> {
			// 调用资产服务获取余额
			String r = getMoney();
			return r;
		};
		// 执行任务
		Future<String> f2 = threadPoolExecutor.submit(c2);
		
		Callable<String> c3 = () -> {
			// 调用活动服务获取优惠券
			String r = getCoupon();
			return r;
		};
		// 执行任务
		Future<String> f3 = threadPoolExecutor.submit(c3);
		
		//数据汇总，获取三个子线程的返回结果
		Map<String, Object> map = new HashMap<>();
		try {
			String userInfo = f1.get();
			String money = f2.get();
			String coupon = f3.get();
			map.put("userInfo", userInfo);
			map.put("money", money);
			map.put("coupon", coupon);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	void test5() throws InterruptedException, ExecutionException {
		Callable<String> c = new Callable<String>() {
			@Override
			public String call() throws Exception {
				Thread.sleep(3000L);
				System.out.println("子任务执行完毕...");
				return "1234";
			}
		};
		FutureTask<String> f = new FutureTask<>(c);
		Thread t = new Thread(f);
		t.start();
		Thread currentThread = Thread.currentThread();
		System.out.println("取消前状态：" + t.isInterrupted());
		boolean b = f.cancel(true);
		System.out.println("取消结果：" + b);
		System.out.println("取消后状态：" + t.isInterrupted());
//		String s = f.get();
//		System.out.println("get结果：" + s);
	}
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ThreadDemo thread = new ThreadDemo();
		thread.testState2();
	}
	
	public String getUserInfo() {
		return "用户信息";
	}
	
	public String getMoney() {
		return "余额";
	}
	
	public String getCoupon() {
		return "优惠券";
	}
}
